package com.gxar.quick.ar.server.base.sdk;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.gxar.common.exception.APIRuntimeException;
import com.gxar.common.utils.JacksonUtils;
import com.gxar.common.utils.StringSpliceUtils;
import com.gxar.common.utils.StringUtils;
import com.gxar.quick.ar.server.base.model.ResultCodeEnum;
import com.gxar.quick.ar.server.base.model.share.info.AccessTokenInfo;
import com.gxar.quick.ar.server.base.model.share.vo.QrCodeVO;
import com.gxar.quick.ar.server.base.model.share.vo.UrlLinkVO;
import lombok.extern.slf4j.Slf4j;
import sun.misc.BASE64Encoder;

import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信小程序SDK
 *
 * @author linsy
 * @version 1.0
 * @created 2024/3/21 16:27
 */
@Slf4j
public class WechatAppSDK {

    /**
     * 获取小程序请求token
     *
     * @param app    app
     * @param secret secret
     * @return 响应
     */
    public static String getAccessToken(String app, String secret) {
        String url = StringSpliceUtils.splice("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}", app, secret);
        try {
            String response = HttpUtil.get(url);
            if (StringUtils.isBlank(response)) {
                throw new APIRuntimeException(ResultCodeEnum.WECHAT_NO_RESPONSE);
            }
            AccessTokenInfo accessTokenInfo = JacksonUtils.parseObject(response, AccessTokenInfo.class);
            String accessToken = accessTokenInfo.getAccess_token();
            if (StringUtils.isBlank(accessToken)) {
                return "";
            }
            return accessToken;
        } catch (Exception e) {
            throw new APIRuntimeException(e);
        }
    }

    /**
     * 生成指定小程序链接
     *
     * @param app    app
     * @param secret secret
     * @param param  参数
     * @param <T>    模型
     * @return 小程序链接
     */
    public static <T extends UrlLinkVO> String generateUrlLink(String app, String secret, T param) {
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("path", param.getPath());
        requestMap.put("query", param.getQuery());
        requestMap.put("is_expire", param.getIsExpire());
        requestMap.put("expire_type", param.getExpireType());
        requestMap.put("expire_interval", param.getExpireInterval());
        requestMap.put("expire_time", param.getExpireTime());
        if (StringUtils.isNotBlank(param.getEnvVersion())) {
            requestMap.put("env_version", param.getEnvVersion());
        }
        String accessToken = getAccessToken(app, secret);
        if (StringUtils.isBlank(accessToken)) {
            throw new APIRuntimeException(ResultCodeEnum.WECHAT_GET_TOKEN_FAIL);
        }
        String getUrl = StringSpliceUtils.splice("https://api.weixin.qq.com/wxa/generate_urllink?access_token={}", accessToken);
        try {
            String response = HttpUtil.post(getUrl, JSON.toJSONString(requestMap));
            if (StringUtils.isBlank(response)) {
                throw new APIRuntimeException(ResultCodeEnum.WECHAT_NO_RESPONSE);
            }
            JSONObject jsonObject = JSON.parseObject(response);
            Integer errcode = jsonObject.getInteger("errcode");
            if (errcode != 0) {
                throw new APIRuntimeException(ResultCodeEnum.WECHAT_EXCEPTION.getRet(), jsonObject.getString("errmsg"));
            }
            return jsonObject.getString("url_link");
        } catch (Exception e) {
            throw new APIRuntimeException(e);
        }
    }

    /**
     * 生成小程序二维码
     *
     * @param app    小程序
     * @param secret 密钥
     * @param param  参数
     * @param <T>    参数模型
     * @return 小程序码
     */
    public static <T extends QrCodeVO> String generateQrCode(String app, String secret, T param) {
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("scene", param.getScene());
        requestMap.put("page", param.getPage());
        if (StringUtils.isNotBlank(param.getEnv())) {
            requestMap.put("env_version", param.getEnv());
        }
        String accessToken = getAccessToken(app, secret);
        if (StringUtils.isBlank(accessToken)) {
            throw new APIRuntimeException(ResultCodeEnum.WECHAT_GET_TOKEN_FAIL);
        }
        String getUrl = StringSpliceUtils.splice("https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={}", accessToken);
        try {
            HttpRequest httpRequest = HttpUtil.createPost(getUrl);
            httpRequest.body(JSON.toJSONString(requestMap));
            HttpResponse response = httpRequest.execute();
            if (response.header("Content-Type").contains("image/jpeg")) {
                byte[] bytes = response.bodyBytes();
                return Base64.getEncoder().encodeToString(bytes);
            } else {
                log.warn("generate QrCode fail: {}", response.body());
                throw new APIRuntimeException(ResultCodeEnum.QR_C0DE_FAIL);
            }
        } catch (Exception e) {
            throw new APIRuntimeException(e);
        }
    }

}
